home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / swag / win-os2.swg / 0046_Huge Memory Allocation Unit - Windows.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-03-26  |  6.8 KB  |  258 lines

  1. {
  2. From: perivar@ibg.uit.no (Per Ivar Steinsund)
  3.  
  4. I've made a unit (Huge) that uses the global-heap to allocate
  5. memory for arrays. The size of the arrays are only limited by
  6. hardware memory.
  7. }
  8. Unit Huge;
  9.  
  10. (***********************************************)
  11. (* Unit for making dynamic arrays and matrix.  *)
  12. (* The elementsize has a limit of 64 kB, but   *)
  13. (* the total size of each array/matrix is only *)
  14. (* limited by available memory.                *)
  15. (*                                             *)
  16. (* Per Ivar Steinsund (1994)                   *)
  17. (*                                             *)
  18. (* Example of use:                             *)
  19. (*                                             *)
  20. (* var J:longint;                              *)
  21. (*     Arr:PHugeRealArray;                     *)
  22. (*                                             *)
  23. (* begin                                       *)
  24. (*    Arr:=new(PHugeRealArray,Init(0,200000,   *)
  25. (*             SizeOf(Real),true));            *)
  26. (*    if Arr^.Data<>nil then                   *)
  27. (*       for J:=0 to 200000 do Arr^.I(J)^:=J/5;*)
  28. (*    Arr^.Done;                               *)
  29. (* end;                                        *)
  30. (*                                             *)
  31. (***********************************************)
  32.  
  33. interface
  34.  
  35. uses  Objects,WinAPI,OMemory,WinTypes;
  36.  
  37. Const
  38.     SegSize=$FFFF;
  39.  
  40. Type
  41.     Adr=record
  42.        Off,Seg:Word;
  43.     end;
  44.  
  45.     PHugeArray=^THugeArray;
  46.     THugeArray=Object(TObject)
  47.        Data:Pointer;
  48.        MinX,MaxX:LongInt;
  49.        ElementSize,ElementsPerSeg:LongInt;
  50.        constructor Init(Min,Max:LongInt; Size:Word; Message:boolean);
  51.        function ChangeSize(Min,Max:LongInt; Message:boolean):boolean;
  52.        function I(X:LongInt):Pointer;
  53.        destructor done; virtual;
  54.        procedure GrabMem(var NewData:Pointer; Range:LongInt;
  55. Change,Message:boolean);
  56.        function GetPtr(Pos:LongInt):Pointer;
  57.     end;
  58.  
  59.     PReal=^Real;
  60.  
  61.     PHugeRealArray=^THugeRealArray;
  62.     THugeRealArray=Object(THugeArray)
  63.        function I(X:LongInt):PReal;
  64.     end;
  65.  
  66.     PHugeMatrix=^THugeMatrix;
  67.     THugeMatrix=Object(THugeArray)
  68.        MinY,MaxY,RangeY:LongInt;
  69.        constructor Init(Min1,Max1,Min2,Max2:LongInt; Size:Word;
  70. Message:boolean);
  71.        function ChangeSize(Min1,Max1,Min2,Max2:LongInt;
  72. Message:boolean):boolean;
  73.        function I(X,Y:LongInt):Pointer;
  74.     end;
  75.  
  76.     PHugeWordMatrix=^THugeWordMatrix;
  77.     THugeWordMatrix=Object(THugeMatrix)
  78.        function I(X,Y:LongInt):PWord;
  79.     end;
  80.  
  81. implementation
  82.  
  83.     constructor THugeArray.Init(Min,Max:LongInt; Size:Word; Message:boolean);
  84.  
  85.     begin
  86.        MinX:=Min;
  87.        MaxX:=Max;
  88.        ElementSize:=Size;
  89.        GrabMem(Data,MaxX-MinX+1,false,Message);
  90.     end;
  91.  
  92.     destructor THugeArray.done;
  93.  
  94.     begin
  95.        GlobalFreePtr(Data);
  96.     end;
  97.  
  98.     function THugeArray.I(X:LongInt):Pointer;
  99.  
  100.     begin
  101.        I:=GetPtr(X-MinX);
  102. {$IFOPT R+}
  103.        if (X<MinX) or (X>MaxX) then
  104.           if id_No=MessageBox(0,'Error in huge array, continue?','Index out of range!',
  105.                               mb_YesNo or mb_IconQuestion) then
  106.           begin
  107.              Done;
  108.              Halt;
  109.           end;
  110. {$ENDIF}
  111.     end;
  112.  
  113.     function THugeArray.ChangeSize(Min,Max:LongInt; Message:boolean):boolean;
  114.  
  115.     var NewData:Pointer;
  116.  
  117.     begin
  118.        MinX:=Min;
  119.        MaxX:=Max;
  120.        GrabMem(NewData,MaxX-MinX+1,true,Message);
  121.        if NewData<>nil then
  122.        begin
  123.           ChangeSize:=true;
  124.           Data:=NewData;
  125.        end
  126.        else ChangeSize:=false;
  127.     end;
  128.  
  129.     procedure THugeArray.GrabMem(var NewData:Pointer; Range:LongInt;
  130. Change,Message:boolean);
  131.  
  132.     var MemSize:LongInt;
  133.  
  134.     begin
  135.        MemSize:=Range*ElementSize;
  136.        if not Change then ElementsPerSeg:=SegSize div ElementSize;
  137.        if (MemSize>SegSize) and (SegSize mod ElementSize<>0) then
  138.           MemSize:=(Range div ElementsPerSeg)*SegSize+ElementSize*(Range mod
  139. ElementsPerSeg);
  140.        if Change then NewData:=GlobalReAllocPtr(Data,MemSize,Gmem_Moveable or
  141. Gmem_NoDiscard)
  142.                  else NewData:=GlobalAllocPtr(Gmem_Moveable or
  143. Gmem_NoDiscard,MemSize);
  144.        if (NewData=nil) and Message then
  145.           MessageBox(0,'It is not possible to allocate enough memory.',
  146.                      'Error',mb_OK or mb_IconInformation);
  147.     end;
  148.  
  149.     function THugeArray.GetPtr(Pos:LongInt):Pointer;
  150.  
  151.     begin
  152.        GetPtr:=Ptr(Adr(Data).Seg+(Pos div ElementsPerSeg)*SelectorInc,
  153.                    Adr(Data).Off+(Pos mod ElementsPerSeg)*ElementSize);
  154.     end;
  155.  
  156.     function THugeRealArray.I(X:LongInt):PReal;
  157.  
  158.     begin
  159.        I:=inherited I(X);
  160.     end;
  161.  
  162.     constructor THugeMatrix.Init(Min1,Max1,Min2,Max2:LongInt; Size:Word;
  163. Message:boolean);
  164.  
  165.     begin
  166.        MinX:=Min1;
  167.        MaxX:=Max1;
  168.        MinY:=Min2;
  169.        MaxY:=Max2;
  170.        RangeY:=1+MaxY-MinY;
  171.        ElementSize:=Size;
  172.        GrabMem(Data,(MaxX-MinX+1)*(MaxY-MinY+1),false,Message);
  173.     end;
  174.  
  175.     function THugeMatrix.ChangeSize(Min1,Max1,Min2,Max2:LongInt;
  176. Message:boolean):boolean;
  177.  
  178.     var NewData:Pointer;
  179.  
  180.     begin
  181.        MinX:=Min1;
  182.        MaxX:=Max1;
  183.        MinY:=Min2;
  184.        MaxY:=Max2;
  185.        RangeY:=1+MaxY-MinY;
  186.        GrabMem(NewData,(MaxX-MinX+1)*(MaxY-MinY+1),true,Message);
  187.        if NewData<>nil then
  188.        begin
  189.           ChangeSize:=true;
  190.           Data:=NewData;
  191.        end
  192.        else ChangeSize:=false;
  193.     end;
  194.  
  195.     function THugeMatrix.I(X,Y:LongInt):Pointer;
  196.  
  197.     begin
  198.        I:=GetPtr(Y-MinY+RangeY*(X-MinX));
  199. {$IFOPT R+}
  200.        if (X<MinX) or (X>MaxX) or (Y<MinY) or (Y>MaxY) then
  201.           if id_No=MessageBox(0,'Error in huge matrix, continue?','Index out of range!',
  202.                               mb_YesNo or mb_IconQuestion) then
  203.           begin
  204.              Done;
  205.              Halt;
  206.           end;
  207. {$ENDIF}
  208.     end;
  209.  
  210.     function THugeWordMatrix.I(X,Y:LongInt):PWord;
  211.  
  212.     begin
  213.        I:=inherited I(X,Y);
  214.     end;
  215.  
  216. end.
  217.  
  218.  
  219. program TestHuge;
  220.  
  221. uses Huge,WinCrt;
  222.  
  223. const Max:LongInt=200000;
  224.       MaxMat:LongInt=2500;
  225.  
  226. var J:longint;
  227.     Arr:PHugeRealArray;
  228.     Mat:PHugeWordMatrix;
  229.  
  230. begin
  231.    Arr:=new(PHugeRealArray,Init(0,Max,
  232.             SizeOf(Real),true));
  233.    if Arr^.Data<>nil then
  234.    begin
  235.       RandSeed:=1;
  236.        for J:=0 to 50 do
  237.          Arr^.I(random(Max))^:=J;
  238.       RandSeed:=1;
  239.       for J:=0 to 50 do
  240.          writeln(Arr^.I(random(Max))^:5:1);
  241.    end;
  242.    Arr^.Done;
  243.    Mat:=new(PHugeWordMatrix,Init(0,MaxMat,0,MaxMat,
  244.             SizeOf(Word),true));
  245.    if Mat^.Data<>nil then
  246.    begin
  247.       RandSeed:=1;
  248.        for J:=0 to 50 do
  249.          Mat^.I(random(MaxMat),random(MaxMat))^:=J;
  250.       RandSeed:=1;
  251.       for J:=0 to 50 do
  252.          writeln(Mat^.I(random(MaxMat),random(MaxMat))^);
  253.    end;
  254.    Mat^.Done;
  255.    writeln('Done');
  256. end.
  257.  
  258.